﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using ServiceLibrary.Callbacks;

namespace ServiceLibrary
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class PumpStationService : IPumpStationService, ICentralTerminalService
    {
        private int _nextStationId = 1000;
        private readonly Dictionary<int, PumpStation> _stations = new Dictionary<int, PumpStation>();
        private readonly Dictionary<int, CentralTerminal> _terminals = new Dictionary<int, CentralTerminal>();

        // IPumpStationService implementation
        public int RegisterPumpStation(string ipAddress, int port, PumpDTO[] pumps)
        {
            var stationId = _nextStationId;
            _stations[stationId] = new PumpStation(stationId, ipAddress, port, pumps, OperationContext.Current.GetCallbackChannel<IPumpStationCallback>());
            Console.WriteLine("Pump Station registered with ID: " + stationId + ", Pumps:");
            foreach (PumpDTO pump in pumps)
            {
                Console.WriteLine("Capacity: " + pump.Capacity + ", Running: " + pump.Running);
            }
            _nextStationId++;
            return stationId;
        }

        public void UpdateWaterlevel(int stationId, int waterlevel)
        {
            Console.WriteLine("UpdateWaterlevel(" + stationId + ", " + waterlevel + ")");
            _stations[stationId].Waterlevel = waterlevel;
        }

        public void SetPumpRunning(int stationId, int pumpIndex, bool running)
        {
            _stations[stationId].Pumps[pumpIndex].Running = running;
        }


        // ICentralTerminalService implementation
        public void RegisterCentralTerminal(int terminalId)
        {
            Console.WriteLine("RegisterCentralTerminal(" + terminalId + ")");
            _terminals[terminalId] = new CentralTerminal(OperationContext.Current.GetCallbackChannel<ICentralTerminalCallback>());
        }

        public void UnregisterCentralTerminal(int terminalId)
        {
            Console.WriteLine("UnregisterCentralTerminal(" + terminalId + ")");
            _terminals.Remove(terminalId);
        }


        public void StartPump(int stationId, int pumpIndex)
        {
            Console.WriteLine("StartPump(" + stationId + ", " + pumpIndex + ")");
            if (_stations.ContainsKey(stationId))
            {
                _stations[stationId].Pumps[pumpIndex].Running = true;
                _stations[stationId].CallbackChannel.OnStartPump(pumpIndex);
            }
        }

        public void StopPump(int stationId, int pumpIndex)
        {
            Console.WriteLine("StopPump(" + stationId + ", " + pumpIndex + ")");
            if (_stations.ContainsKey(stationId))
            {
                _stations[stationId].Pumps[pumpIndex].Running = false;
                _stations[stationId].CallbackChannel.OnStopPump(pumpIndex);
            }
        }

        public List<PumpStationDTO> GetPumpStations()
        {
            Console.WriteLine("GetPumpStations()");
            return _stations.Values.Select(station => new PumpStationDTO { Id = station.Id, IPAddress = station.IPAddress, Port = station.Port, Waterlevel = station.Waterlevel}).ToList();
        }

        public List<PumpDTO> GetPumps(int stationId)
        {
            Console.WriteLine("GetPumps(" + stationId + ")");
            return _stations[stationId].Pumps.Select(pump => new PumpDTO
            {
                Capacity = pump.Capacity,
                Running = pump.Running
            }).ToList();
        }


        public void Subscribe(int terminalId, int stationId)
        {
            Console.WriteLine("Subscribe(" + terminalId + ", " + stationId + ")");
            _stations[stationId].Changed += _terminals[terminalId].StationChanged;
        }

        public void Unsubscribe(int terminalId, int stationId)
        {
            Console.WriteLine("Unsubscribe(" + terminalId + ", " + stationId + ")");
            _stations[stationId].Changed -= _terminals[terminalId].StationChanged;
        }
    }
}
